package com.yanqu.road.server.manger.union;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.enums.eUnionPosition;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUser;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.bussiness.union.activitygroup.UnionActivityGroupBusiness;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.ServerType;
import com.yanqu.road.utils.date.DateHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public abstract class BaseUnionActivityGroupMgr extends TempMgr {

    protected static final Object lock = new Object();

    /**
     * 商会活动名单数据    key：活动ID，分组ID
     */
    protected static final Map<Integer, Map<Integer, UnionActivityGroup>> activityGroupMap = new ConcurrentHashMap<>();

    // 缓存：玩家找商会
    protected static final Map<Integer, Map<Long, UnionActivityGroupUnion>> userToUnionCacheMap = new ConcurrentHashMap<>();

    // ----------------------------------------------------

    public static void putGroupMap(int activityId, Map<Integer, UnionActivityGroup> groupMap) {
        activityGroupMap.put(activityId, groupMap);
        clearCache(activityId);
        getLogger().debug("活动ID {} 添加分组数据， 一共 {} 组。", activityId, groupMap.size());
    }

    /**
     * 慎用，锁名单了，只能更新新成员
     */
    public static void updateGroupUnion(UnionActivityGroupUnion updateUnion) {
        Map<Integer, UnionActivityGroup> groupMap = activityGroupMap.get(updateUnion.getActivityId());
        if (groupMap == null) {
            return;
        }
        UnionActivityGroup group = groupMap.get(updateUnion.getGroupId());
        if (group == null) {
            return;
        }
        synchronized (lock) {
            UnionActivityGroupUnion oldUnion = group.getUnionDataMap().get(updateUnion.getUnionUid());
            if (oldUnion == null) {
                updateUnion.setInsertOption();
                group.getUnionDataMap().put(updateUnion.getUnionUid(), updateUnion);
            } else {
                oldUnion.copyData(updateUnion);
            }
            clearCache(updateUnion.getActivityId());
        }
    }

    public static void clearCache(int activityId) {
        synchronized (lock) {
            Map<Long, UnionActivityGroupUnion> map = userToUnionCacheMap.get(activityId);
            if (map != null) {
                map.clear();
            }
        }
    }

    public static void loadDbData(int serverType, long serverId) {
        // 按区服读活动分组数据
        String yesterday = DateHelper.getCurrentDateTimeString(System.currentTimeMillis() - DateHelper.DAY_MILLIONS);
        Map<Integer, Map<Integer, UnionActivityGroup>> tempActivityGroupMap = UnionActivityGroupBusiness.getNoEndUnionActivityGroupMap(yesterday, serverType, serverId);

        int channelId;
        if (serverType == ServerType.SERVER_CROSS_2 || serverType == ServerType.CENTER_CROSS_2) {
            channelId = ConfigHelper.getInt("channelId");
        } else if (serverType == ServerType.SERVER_GAME) {
            channelId = ServerListMgr.getServerInfo(serverId).getChannelId();
        } else {
            throw new RuntimeException("拿不到channelId");
        }

        // zkt todo 热更代码记得优化 2023年3月28日16:05:55
        // 过滤非本渠道活动
        Map<Integer, ActivityInfo> activityInfoMap = ActivityBussiness.getActivityInfoMap(new ArrayList<>(tempActivityGroupMap.keySet()));
        for (Map.Entry<Integer, Map<Integer, UnionActivityGroup>> entry : tempActivityGroupMap.entrySet()) {
            int activityId = entry.getKey();
            ActivityInfo info = activityInfoMap.get(activityId);
            boolean channelCorrect = false;
            if (info != null) {
                for (long tempServerId : info.getServerIdList()) {
                    ServerInfo serverInfo = ServerListMgr.getServerInfo(tempServerId);
                    if (serverInfo == null) {
                        continue;
                    }
                    channelCorrect = serverInfo.getChannelId() == channelId;
                    break;
                }
                if (!channelCorrect) {
                    tempActivityGroupMap.remove(activityId);
                }
            }
        }

        // 按活动读商会数据
        for (Map.Entry<Integer, Map<Integer, UnionActivityGroup>> entry : tempActivityGroupMap.entrySet()) {
            int activityId = entry.getKey();
            Map<Integer, UnionActivityGroup> groupMap = entry.getValue();
            List<Integer> groupIdList = groupMap.values().stream().mapToInt(UnionActivityGroup::getGroupId).boxed().collect(Collectors.toList());
            List<UnionActivityGroupUnion> unionList = UnionActivityGroupBusiness.getUnionActivityGroupUnionList(activityId, groupIdList);
            for (UnionActivityGroupUnion union : unionList) {
                UnionActivityGroup group = groupMap.get(union.getGroupId());
                if (group != null) {
                    group.getUnionDataMap().put(union.getUnionUid(), union);
                }
            }
        }

        // 生成缓存
        Map<Integer, Map<Long, Integer>> tempActivityUserGroupMap = new ConcurrentHashMap<>();
        for (Map<Integer, UnionActivityGroup> groupMap : tempActivityGroupMap.values()) {
            for (UnionActivityGroup group : groupMap.values()) {
                for (UnionActivityGroupUnion union : group.getUnionDataMap().values()) {
                    for (UnionActivityGroupUser user : union.getUserMap().values()) {
                        tempActivityUserGroupMap.putIfAbsent(union.getActivityId(), new ConcurrentHashMap<>());
                        tempActivityUserGroupMap.get(union.getActivityId()).put(user.getUserId(), union.getGroupId());
                    }
                }
            }
        }

        activityGroupMap.clear();
        activityGroupMap.putAll(tempActivityGroupMap);
        userToUnionCacheMap.clear();
    }

    public static boolean haveGroup(int activityId) {
        Map<Integer, UnionActivityGroup> groupMap = activityGroupMap.get(activityId);
        return groupMap != null && groupMap.size() > 0;
    }

    // ----------------------------------------------------

    public static UnionActivityGroup getGroupData(int activityId, int groupId) {
        Map<Integer, UnionActivityGroup> groupMap = activityGroupMap.get(activityId);
        if (groupMap != null) {
            return groupMap.get(groupId);
        }
        return null;
    }

    public static UnionActivityGroupUnion getUnionData(int activityId, long userId) {
        // 读缓存
        Map<Long, UnionActivityGroupUnion> userMap = userToUnionCacheMap.get(activityId);
        if (userMap != null) {
            UnionActivityGroupUnion union = userMap.get(userId);
            if (union != null) {
                return union;
            }
        }
        // 遍历找
        Map<Integer, UnionActivityGroup> groupMap = activityGroupMap.get(activityId);
        if (groupMap != null) {
            for (UnionActivityGroup group : groupMap.values()) {
                for (UnionActivityGroupUnion union : group.getUnionDataMap().values()) {
                    if (union.getUserMap().containsKey(userId)) {
                        // 写缓存
                        synchronized (lock) {
                            userToUnionCacheMap.putIfAbsent(activityId, new ConcurrentHashMap<>());
                            userToUnionCacheMap.get(activityId).put(userId, union);
                        }
                        return union;
                    }
                }

            }
        }
        return null;
    }

    public static UnionActivityGroupUnion getUnionData(int activityId, String unionUid) {
        Map<Integer, UnionActivityGroup> groupMap = activityGroupMap.get(activityId);
        if (groupMap != null) {
            for (UnionActivityGroup group : groupMap.values()) {
                if (group.getUnionDataMap().containsKey(unionUid)) {
                    return group.getUnionDataMap().get(unionUid);
                }
            }
        }
        return null;
    }

    public static UnionActivityGroupUnion getUnionData(int activityId, String unionUid, int groupId) {
        Map<Integer, UnionActivityGroup> groupMap = activityGroupMap.get(activityId);
        if (groupMap != null && groupMap.containsKey(groupId)) {
           return groupMap.get(groupId).getGroupUnion(unionUid);
        }
        return null;
    }

    public static int getGroupId(ActivityInfo info, String unionUid) {
        // 判断无需分组活动
        if (!UnionActivityGroupHelper.needGroup(info)) {
            return UnionActivityGroupHelper.NO_NEED_GROUP_ID;
        }
        // 找分组
        UnionActivityGroupUnion unionData = getUnionData(info.getActivityId(), unionUid);
        return unionData == null ? UnionActivityGroupHelper.NO_GROUP_ID : unionData.getGroupId();
    }

    public static int getGroupId(ActivityInfo info, long userId) {
        // 判断无需分组活动
        if (!UnionActivityGroupHelper.needGroup(info)) {
            return UnionActivityGroupHelper.NO_NEED_GROUP_ID;
        }
        // 拿分组
        UnionActivityGroupUnion unionData = getUnionData(info.getActivityId(), userId);
        if (unionData != null) {
            return unionData.getGroupId();
        }
        return UnionActivityGroupHelper.NO_GROUP_ID;
    }

    public static Map<Integer, Map<Integer, UnionActivityGroup>> getGroupMap() {
        return activityGroupMap;
    }

    public static Map<Integer, UnionActivityGroup> getGroupMap(int activityId) {
        return activityGroupMap.get(activityId);
    }

    public static String getUnionUid(int activityId, long userId) {
        UnionActivityGroupUnion unionData = getUnionData(activityId, userId);
        if (unionData != null) {
            return unionData.getUnionUid();
        }
        return "";
    }

    public static int getUnionPosition(int activityId, long userId){
        UnionActivityGroupUnion unionData = getUnionData(activityId, userId);
        if(unionData == null){
            return eUnionPosition.Member.getValue();
        }
        UnionActivityGroupUser groupUser = unionData.getUserMap().get(userId);
        if(groupUser == null){
            return eUnionPosition.Member.getValue();
        }
        return groupUser.getPosition();
    }

    public static List<Long> getUnionUserList(int activityId, String unionUid){
        List<Long> userIdList = new ArrayList<>();
        UnionActivityGroupUnion unionData = getUnionData(activityId, unionUid);
        if(unionData == null){
            return userIdList;
        }
        for (Map.Entry<Long, UnionActivityGroupUser> entry : unionData.getUserMap().entrySet()) {
            userIdList.add(entry.getKey());
        }

        return userIdList;
    }
}
